// src/book/book.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Brackets } from 'typeorm';
import { Book } from './book.entity';
import {
  paginate,
  Pagination,
  IPaginationOptions,
} from 'nestjs-typeorm-paginate';
// API解释：
/*  
 paginate:神级函数！一句话完成分页 + 总数统计 + 生成链接自动执行 LIMIT ? OFFSET ? 和 COUNT(*)

 Pagination<Book> 是一个泛型类，用于表示分页结果。返回的数据类型：包含 items + meta + links标准分页响应结构

 IPaginationOptions 是一个接口，用于表示分页选项,告诉 paginate 函数的配置项page、limit、route 必须传。
  */
import { PaginationOptions } from '../../types/book';

@Injectable()
export class BookService {
  constructor(
    @InjectRepository(Book)
    private readonly bookRepository: Repository<Book>
  ) {}

  // 分页
  async paginate(
    options: PaginationOptions,
    baseRoute: string
  ): Promise<Pagination<Book>> {
    // 构建查询构建器
    const qb = this.bookRepository.createQueryBuilder('book');

    // 如果有搜索词，则添加多字段模糊搜索
    if (options.keyword) {
      qb.andWhere(
        new Brackets(sq => {
          sq.where('book.title LIKE :keyword', {
            keyword: `%${options.keyword}%`,
          })
            .orWhere('book.author LIKE :keyword', {
              keyword: `%${options.keyword}%`,
            })
            .orWhere('book.publisher LIKE :keyword', {
              keyword: `%${options.keyword}%`,
            })
            .orWhere('book.bookid LIKE :keyword', {
              keyword: `%${options.keyword}%`,
            })
            .orWhere('book.language LIKE :keyword', {
              keyword: `%${options.keyword}%`,
            });
        })
      );
    }

    // 排序白名单（防SQL注入）
    const allowedSortFields = [
      'id',
      'title',
      'author',
      'publisher',
      'bookid',
      'category',
      'language',
      'created_at',
      'updated_at',
    ];
    // 如果有排序字段且在白名单内，则添加排序
    if (options.sort && allowedSortFields.includes(options.sort)) {
      if (options.order === 'ASC') {
        qb.orderBy(`book.${options.sort}`, 'ASC');
      } else {
        qb.orderBy(`book.${options.sort}`, 'DESC');
      }
    } else {
      if (options.order) {
        qb.orderBy('book.id', options.order);
      } else {
        qb.orderBy('book.id', 'DESC'); // 默认按照id最新在前
      }
    }
    // 分页配置 之前Controller就想page和limit从路由中过滤掉 就是为了下面的route能纯净 不包含page和limit
    const paginateOptions: IPaginationOptions = {
      page: options.page,
      limit: options.limit,
      route: baseRoute, // 传递基础路由，确保分页链接保留所有参数
    };
    // 根据查找的数据完成自动分页
    return paginate<Book>(qb, paginateOptions);
  }

  async findOne(id: number): Promise<Book | null> {
    return this.bookRepository.findOneBy({ id });
  }
}
